<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.5.2" />
<title></title>
<style type="text/css">
/* Debug borders */
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
/*
  border: 1px solid red;
*/
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

tt {
  color: navy;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  font-family: sans-serif;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}

div.sectionbody {
  font-family: serif;
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}

pre {
  padding: 0;
  margin: 0;
}

span#author {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  font-size: 1.1em;
}
span#email {
}
span#revnumber, span#revdate, span#revremark {
  font-family: sans-serif;
}

div#footer {
  font-family: sans-serif;
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
div#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
div#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

div#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #dddddd;
  color: #777777;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > div.content {
  white-space: pre;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-family: sans-serif;
  font-weight: bold;
}
tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}


@media print {
  div#footer-badges { display: none; }
}

div#toc {
  margin-bottom: 2.5em;
}

div#toctitle {
  color: #527bbd;
  font-family: sans-serif;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}
/* Workarounds for IE6's broken and incomplete CSS2. */

div.sidebar-content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}
div.sidebar-title, div.image-title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  margin-top: 0.0em;
  margin-bottom: 0.5em;
}

div.listingblock div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock-attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock-content {
  white-space: pre;
}
div.verseblock-attribution {
  padding-top: 0.75em;
  text-align: left;
}

div.exampleblock-content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

/* IE6 sets dynamically generated links as visited. */
div#toc a:visited { color: blue; }
</style>
<script type="text/javascript">
/*<![CDATA[*/
window.onload = function(){asciidoc.footnotes();}
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  var cont = document.getElementById("content");
  var noteholder = document.getElementById("footnotes");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      // Use [\s\S] in place of . so multi-line matches work.
      // Because JavaScript has no s (dotall) regex flag.
      note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      spans[i].innerHTML =
        "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
        "' title='View footnote' class='footnote'>" + n + "</a>]";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
}

}
/*]]>*/
</script>
</head>
<body>
<div id="header">
</div>
<div id="content">

<h2 id="_working_with_an_event_loop">Working with an event loop</h2>
<div class="sectionbody">
<h3 id="_running_the_loop">Running the loop</h3><div style="clear:left"></div>
<div class="paragraph"><p>Once you have an event_base with some events registered (see the next section
about how to create and register events), you will want Libevent to wait for
events and alert you about them.</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt>#define EVLOOP_ONCE             0x01
#define EVLOOP_NONBLOCK         0x02
#define EVLOOP_NO_EXIT_ON_EMPTY 0x04

<strong>int</strong> event_base_loop(<strong>struct</strong> event_base *base, <strong>int</strong> flags);</tt></pre>
</div></div>
<div class="paragraph"><p>By default, the event_base_loop() function <em>runs</em> an event_base until there
are no more events registered in it.  To run the loop, it repeatedly checks
whether any of the registered events has triggered (for example, if a read
event&#8217;s file descriptor is ready to read, or if a timeout event&#8217;s timeout is
ready to expire).  Once this happens, it marks all triggered events as
"active", and starts to run them.</p></div>
<div class="paragraph"><p>You can change the behavior of event_base_loop() by setting one or more flags
in its <em>flags</em> argument.  If EVLOOP_ONCE is set, then the loop will wait
until some events become active, then run active events until there are no
more to run, then return.  If EVLOOP_NONBLOCK is set, then
the loop will not wait for events to trigger: it will only check whether
any events are ready to trigger immediately, and run their callbacks if so.</p></div>
<div class="paragraph"><p>Ordinarily, the loop will exit as soon as it has no pending or active events.
You can
override this behavior by passing the EVLOOP_NO_EXIT_ON_EMPTY flag---for
example, if you&#8217;re going to be adding events from some other thread.  If you
do set EVLOOP_NO_EXIT_ON_EMPTY, the loop will keep running until somebody
calls event_base_loopbreak(), or calls event_base_loopexit(), or an error
occurs.</p></div>
<div class="paragraph"><p>When it is done, event_base_loop() returns 0 if it exited normally, -1 if
it exited because of some unhandled error in the backend, and 1 if it exited
because there were no more pending or active events.</p></div>
<div class="paragraph"><p>To aid in understanding, here&#8217;s an approximate summary of the event_base_loop
algorithm:</p></div>
<div class="listingblock">
<div class="title">Pseudocode</div>
<div class="content">
<pre><tt><strong>while</strong> (any events are registered with the loop,
        or EVLOOP_NO_EXIT_ON_EMPTY was set) {

    <strong>if</strong> (EVLOOP_NONBLOCK was set, or any events are already active)
        If any registered events have triggered, mark them active.
    <strong>else</strong>
        Wait until at least one event has triggered, and mark it active.

    <strong>for</strong> (p = 0; p &lt; n_priorities; ++p) {
       <strong>if</strong> (any event with priority of p is active) {
          Run all active events with priority of p.
          <strong>break</strong>; /* Do not run any events of a less important priority */
       }
    }

    <strong>if</strong> (EVLOOP_ONCE was set or EVLOOP_NONBLOCK was set)
       <strong>break</strong>;
}</tt></pre>
</div></div>
<div class="paragraph"><p>As a convenience, you can also call:</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_base_dispatch(<strong>struct</strong> event_base *base);</tt></pre>
</div></div>
<div class="paragraph"><p>The event_base_dispatch() call is the same as event_base_loop(), with no
flags set.  Thus, it keeps running until there are no more registered events
or until event_base_loopbreak() or event_base_loopexit() is called.</p></div>
<div class="paragraph"><p>These functions are defined in &lt;event2/event.h&gt;.  They have existed since
Libevent 1.0.</p></div>
<h3 id="_stopping_the_loop">Stopping the loop</h3><div style="clear:left"></div>
<div class="paragraph"><p>If you want an active event loop to stop running before all events are
removed from it, you have two slightly different functions you can call.</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_base_loopexit(<strong>struct</strong> event_base *base,
                        <strong>const</strong> <strong>struct</strong> timeval *tv);
<strong>int</strong> event_base_loopbreak(<strong>struct</strong> event_base *base);</tt></pre>
</div></div>
<div class="paragraph"><p>The event_base_loopexit() function tells an event_base to stop looping after
a given time has elapsed.  If the <em>tv</em> argument is NULL, the event_base stops
looping without a delay.  If the event_base is currently running callbacks
for any active
events, it will continue running them, and not exit until they have all been
run.</p></div>
<div class="paragraph"><p>The event_base_loopbreak() function tells the event_base to exit its loop
immediately.  It differs from event_base_loopexit(base, NULL) in that if
the event_base is currently running callbacks for any active events, it will
exit
immediately after finishing the one it&#8217;s currently processing.</p></div>
<div class="paragraph"><p>Note also that event_base_loopexit(base,NULL) and event_base_loopbreak(base)
act differently when no event loop is running: loopexit schedules the next
instance of the event loop to stop right after the next round of callbacks
are run (as if it had been invoked with EVLOOP_ONCE) whereas loopbreak only
stops a currently running loop, and has no effect if the event loop isn&#8217;t
running.</p></div>
<div class="paragraph"><p>Both of these methods return 0 on success and -1 on failure.</p></div>
<div class="listingblock">
<div class="title">Example: Shut down immediately</div>
<div class="content">
<pre><tt>#include &lt;event2/event.h&gt;

<i>/* Here's a callback function that calls loopbreak */</i>
<strong>void</strong> cb(<strong>int</strong> sock, <strong>short</strong> what, <strong>void</strong> *arg)
{
    <strong>struct</strong> event_base *base = arg;
    event_base_loopbreak(base);
}

<strong>void</strong> main_loop(<strong>struct</strong> event_base *base, evutil_socket_t watchdog_fd)
{
    <strong>struct</strong> event *watchdog_event;

<i>    /* Construct a new event to trigger whenever there are any bytes to</i>
<i>       read from a watchdog socket.  When that happens, we'll call the</i>
<i>       cb function, which will make the loop exit immediately without</i>
<i>       running any other active events at all.</i>
<i>     */</i>
    watchdog_event = event_new(base, watchdog_fd, EV_READ, cb, base);

    event_add(watchdog_event, NULL);

    event_base_dispatch(base);
}</tt></pre>
</div></div>
<div class="listingblock">
<div class="title">Example: Run an event loop for 10 seconds, then exit.</div>
<div class="content">
<pre><tt>#include &lt;event2/event.h&gt;

<strong>void</strong> run_base_with_ticks(<strong>struct</strong> event_base *base)
{
  <strong>struct</strong> timeval ten_sec;

  ten_sec.tv_sec = 10;
  ten_sec.tv_usec = 0;

<i>  /* Now we run the event_base for a series of 10-second intervals, printing</i>
<i>     "Tick" after each.  For a much better way to implement a 10-second</i>
<i>     timer, see the section below about persistent timer events. */</i>
  <strong>while</strong> (1) {
<i>     /* This schedules an exit ten seconds from now. */</i>
     event_base_loopexit(base, &amp;ten_sec);

     event_base_dispatch(base);
     puts("Tick");
  }
}</tt></pre>
</div></div>
<div class="paragraph"><p>Sometimes you may want to tell whether your call to event_base_dispatch() or
event_base_loop() exited normally, or because of a call to
event_base_loopexit() or event_base_break().  You can use these functions to
tell whether loopexit or break was called:</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_base_got_exit(<strong>struct</strong> event_base *base);
<strong>int</strong> event_base_got_break(<strong>struct</strong> event_base *base);</tt></pre>
</div></div>
<div class="paragraph"><p>These two functions will return true if the loop was stopped with
event_base_loopexit() or event_base_break() respectively, and false
otherwise.  Their values will be reset the next time you start the event
loop.</p></div>
<div class="paragraph"><p>These functions are declared in &lt;event2/event.h&gt;.  The event_break_loopexit()
function was first implemented in Libevent 1.0c; event_break_loopbreak() was
first implemented in Libevent 1.4.3.</p></div>
<h3 id="_re_checking_for_events">Re-checking for events</h3><div style="clear:left"></div>
<div class="paragraph"><p>Ordinarily, Libevent checks for events, then runs all the active events
with the highest priority, then checks for events again, and so on.  But
sometimes you might want to stop Libevent right after the current
callback has been run, and tell it to scan again.  By analogy to
event_base_loopbreak(), you can do this with the function
event_base_loopcontinue().</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_base_loopcontinue(<strong>struct</strong> event_base *);</tt></pre>
</div></div>
<div class="paragraph"><p>Calling event_base_loopcontinue() has no effect if we aren&#8217;t currently
running event callbacks.</p></div>
<div class="paragraph"><p>This function was introduced in Libevent 2.1.2-alpha.</p></div>
<h3 id="_checking_the_internal_time_cache">Checking the internal time cache</h3><div style="clear:left"></div>
<div class="paragraph"><p>Sometimes you want to get an approximate view of the current time inside
an event callback, and you want to get it without calling gettimeofday()
yourself (presumably because your OS implements gettimeofday() as a
syscall, and you&#8217;re trying to avoid syscall overhead).</p></div>
<div class="paragraph"><p>From within a callback, you can ask Libevent for its view of the current
time when it began executing this round of callbacks:</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_base_gettimeofday_cached(<strong>struct</strong> event_base *base,
    <strong>struct</strong> timeval *tv_out);</tt></pre>
</div></div>
<div class="paragraph"><p>The event_base_gettimeofday_cached() function sets the value of its
<em>tv_out</em> argument to the cached time if the event_base is currently
executing callbacks.  Otherwise, it calls evutil_gettimeofday() for the
actual current time.  It returns 0 on success, and negative on failure.</p></div>
<div class="paragraph"><p>Note that since the timeval is cached when Libevent starts running
callbacks, it will be at least a little inaccurate. If your callbacks
take a long time to run, it may be <strong>very</strong> inaccurate.  To force an immediate
cache update, you can call this function:</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_base_update_cache_time(<strong>struct</strong> event_base *base);</tt></pre>
</div></div>
<div class="paragraph"><p>It returns 0 on success and -1 on failure, and has no effect if the base was
not running its event loop.</p></div>
<div class="paragraph"><p>The event_base_gettimeofday_cached() function was new in Libevent
2.0.4-alpha.  Libevent 2.1.1-alpha added event_base_update_cache_time().</p></div>
<h3 id="_dumping_the_event_base_status">Dumping the event_base status</h3><div style="clear:left"></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>void</strong> event_base_dump_events(<strong>struct</strong> event_base *base, FILE *f);</tt></pre>
</div></div>
<div class="paragraph"><p>For help debugging your program (or debugging Libevent!) you might sometimes
want a complete list of all events added in the event_base and their status.
Calling event_base_dump_events() writes this list to the stdio file provided.</p></div>
<div class="paragraph"><p>The list is meant to be human-readable; its format <strong>will</strong> change in future
versions of Libevent.</p></div>
<div class="paragraph"><p>This function was introduced in Libevent 2.0.1-alpha.</p></div>
<h3 id="_running_a_function_over_every_event_in_an_event_base">Running a function over every event in an event_base</h3><div style="clear:left"></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>typedef</strong> <strong>int</strong> (*event_base_foreach_event_cb)(<strong>const</strong> <strong>struct</strong> event_base *,
    <strong>const</strong> <strong>struct</strong> event *, <strong>void</strong> *);

<strong>int</strong> event_base_foreach_event(<strong>struct</strong> event_base *base,
                             event_base_foreach_event_cb fn,
                             <strong>void</strong> *arg);</tt></pre>
</div></div>
<div class="paragraph"><p>You can use event_base_foreach_event() to iterate over every currently
active or pending event associated with an event_base().  The provided
callback will be invoked exactly once per event, in an unspecified
order.  The third argument of event_base_foreach_event() will be passed
as the third argument to each invocation of the callback.</p></div>
<div class="paragraph"><p>The callback function must return 0 to continue iteration, or some other
integer to stop iterating. Whatever value the callback function finally
returns will then be returned by event_base_foreach_function().</p></div>
<div class="paragraph"><p>Your callback function <strong>must not</strong> modify any of the events that it
receives, or add or remove any events to the event base, or otherwise
modify any event associated with the event base, or undefined behavior
can occur, up to or including crashes and heap-smashing.</p></div>
<div class="paragraph"><p>The event_base lock will be held for the duration of the call to
event_base_foreach_event()&#8201;&#8212;&#8201;this will block other threads from doing
anything useful with the event_base, so make sure that your callback
doesn&#8217;t take a long time.</p></div>
<div class="paragraph"><p>This function was added in Libevent 2.1.2-alpha.</p></div>
<h3 id="_obsolete_event_loop_functions">Obsolete event loop functions</h3><div style="clear:left"></div>
<div class="paragraph"><p>As discussed above, older versions of Libevent APIs had a global
notion of a "current" event_base.</p></div>
<div class="paragraph"><p>Some of the event loop functions in this section had variants that
operated on the current base.  These functions behaved as the current
functions, except that they took no base argument.</p></div>
<div class="tableblock">
<table rules="all"
width="85%"
frame="border"
cellspacing="0" cellpadding="4">
<col width="50%" />
<col width="50%" />
<thead>
<tr>
<th align="left" valign="top"> Current function              </th>
<th align="left" valign="top"> Obsolete current-base version</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table">event_base_dispatch()</p></td>
<td align="left" valign="top"><p class="table">event_dispatch()</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">event_base_loop()</p></td>
<td align="left" valign="top"><p class="table">event_loop()</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">event_base_loopexit()</p></td>
<td align="left" valign="top"><p class="table">event_loopexit()</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">event_base_loopbreak()</p></td>
<td align="left" valign="top"><p class="table">event_loopbreak()</p></td>
</tr>
</tbody>
</table>
</div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">Because event_base did not support locking before Libevent 2.0,
these functions weren&#8217;t completely threadsafe: it was not permissible
to call the _loopbreak() or _loopexit() functions from a thread other
than the one executing the event loop.</td>
</tr></table>
</div>
</div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Last updated 2014-12-15 09:43:03 EDT
</div>
</div>
</body>
</html>
